package org.apache.ibatis.demo.test;

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.demo.dao.BlogMapper;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * @Date 2021/2/27 21:38
 * @Created mobian
 * @Description 手动编写识别注解内部的sql语句案例
 */
public class Demo4 {
  public static void main(String[] args) {
    BlogMapper blogMapper = (BlogMapper) Proxy.newProxyInstance(Demo3.class.getClassLoader(), new Class<?>[]{BlogMapper.class}, new InvocationHandler() {

      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Select annotation = method.getAnnotation(Select.class);
        if (annotation != null) {
          String[] value = annotation.value();
          //获取我们的sql语句
          String sql = value[0];

          HashMap<String, Object> argsMap = new HashMap<>();
          if (args != null) {
            for (int i = 0; i < args.length; i++) {
              argsMap.put("id", args[i]);
            }

            String newSQL = parseSQL(sql, argsMap);
            //获取我们传入的参数
            System.out.println(sql);
            System.out.println(newSQL);
          }

        }
        return null;
      }
    });

//    blogMapper.queryAllBlogList();
    blogMapper.queryBlogListById("11");


  }

  public static String parseSQL(String sql, Map<String, Object> argsMap) {
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < sql.length(); i++) {
      char s = sql.charAt(i);
      if (s == '#') {
        if (sql.charAt(++i) != '{') throw new RuntimeException("sql格式异常，缺少 { ");

        //解析参数名字
        String argName = parseParam(sql, i, sb);
        Object argValue = argsMap.get(argName);
        sb.append(argValue);
        return sb.toString();
      }
      sb.append(s);
    }


    return sb.toString();
  }

  public static String parseParam(String sql, int index, StringBuilder sqlFrag) {
    StringBuilder stringBuilder = new StringBuilder();
    index++;
    for (; index < sql.length(); index++) {
      char c = sql.charAt(index);
      if (c != '}') {
        stringBuilder.append(c);
        continue;
      }
      if (c == '}') {
        return stringBuilder.toString();
      }
    }

    throw  new RuntimeException("SQL格式异常");
  }
}
